package com.hefan.api.service.pay;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.cat.common.meta.UserTypeEnum;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.cat.common.entity.ResultBean;
import com.cat.common.meta.PaymentTypeEnum;
import com.cat.common.meta.ResultCode;
import com.cat.common.meta.TradeLogPayStatusEnum;
import com.cat.common.util.BigDecimalCalUtil;
import com.hefan.api.service.UserLocalService;
import com.hefan.pay.bean.CurrencyExchange;
import com.hefan.pay.bean.CurrencyRecharge;
import com.hefan.pay.bean.PayExtendVo;
import com.hefan.pay.bean.TradeLog;
import com.hefan.pay.itf.CurrentRechargeService;
import com.hefan.pay.itf.PayOpreateHandlerService;
import com.hefan.pay.itf.TradeLogService;
import com.hefan.user.bean.WebUser;
import com.hefan.user.itf.WebUserService;

/**
 * Created by lxw on 2016/10/12.
 */
@Component
public class PayLocalService {

	@Reference
	private WebUserService webUserService;
	@Reference
	private CurrentRechargeService currentRechargeService;

	@Reference
	private PayOpreateHandlerService payOpreateHandlerService;

	@Reference
	private TradeLogService tradeLogService;

	@Autowired
	private UserLocalService userLocalservice;

	/**
	 * 支付回调通知成功后进行用户增加饭票|计算费率队列操作
	 * 
	 * @param tradeLog
	 */
	public void payNotifySuccessHandler(TradeLog tradeLog) {
		WebUser webUser = webUserService.getWebUserInfoByUserId(tradeLog.getUserId());
		if (webUser != null) {
			long payBeforeFanpiao = 0;
			long payAfterFanpiao = 0;
			// 成功给用户增加饭票
			if (tradeLog.getPayStatus() == TradeLogPayStatusEnum.PAY_SUCCESS.getPayStatus()
					|| tradeLog.getPayStatus() == TradeLogPayStatusEnum.PAY_NOTIFY_SUCCESS.getPayStatus()) {
				int rowNum = webUserService.incrWebUserBalance(tradeLog.getUserId(), tradeLog.getIncomeAmount());
				payBeforeFanpiao = webUser.getBalance();
				payAfterFanpiao = webUser.getBalance() + tradeLog.getIncomeAmount();
			}
			tradeLog.setPayBeforeFanpiao(payBeforeFanpiao);
			tradeLog.setPayAfterFanpiao(payAfterFanpiao);
			tradeLogService.thridPartyNotfiySuccessOprate(tradeLog);
		}
	}

	/**
	 * 支付下单
	 * 
	 * @param paymentTypeEnum
	 * @param tradeLog
	 * @param vo
	 * @param currencyRechargeId
	 * @param request
	 * @return
	 */
	public ResultBean createOrder(PaymentTypeEnum paymentTypeEnum, TradeLog tradeLog, PayExtendVo vo,
			int currencyRechargeId, HttpServletRequest request) {
		ResultBean resultBean = new ResultBean(ResultCode.SUCCESS, null);
		WebUser user = userLocalservice.getWebUserByUserId(tradeLog.getUserId());
		if (user == null) {
			return new ResultBean(ResultCode.LoginUserIsNotExist, null);
		}
		if(UserTypeEnum.isVirtualUser(user.getUserType())) {  //虚拟用户不能进行该操作
			return new ResultBean(ResultCode.VirtualUserNotOpreate,null);
		}
		Map paymentExtendMap = new HashedMap();
		// 获取兑换比例和反计算例
		ResultBean<Map<String, CurrencyExchange>> exchangeBean = this.findExchangeBeanInfo(paymentTypeEnum);
		if (exchangeBean.getCode() != ResultCode.SUCCESS.get_code()) {
			return exchangeBean;
		}
		// 充值比例
		CurrencyExchange rmbExchangeFp = exchangeBean.getData().get("rmbExchangeFp");
		paymentExtendMap.put("rmbExchangeFp", rmbExchangeFp);
		// 反计算比例
		CurrencyExchange fpExchangeRmb = exchangeBean.getData().get("fpExchangeRmb");
		paymentExtendMap.put("fpExchangeRmb", fpExchangeRmb);
		//如果为苹果内购获取苹果内购的产品code
		String iosProductCode = "";
		if (currencyRechargeId != 0) {
			// 获取充值赠送信息
			ResultBean<CurrencyRecharge> rechangeResult = this
					.queryCurrencyRecharge(paymentTypeEnum.getRechargeStatus(), currencyRechargeId);
			if (rechangeResult.getCode() != ResultCode.SUCCESS.get_code()) {
				return rechangeResult;
			}
			CurrencyRecharge currentRecharge = rechangeResult.getData();
			paymentExtendMap.put("currentRecharge", currentRecharge);
			iosProductCode =  currentRecharge.getIosProductCode();
			// 饭票数
			tradeLog.setIncome(currentRecharge.getAmount());
			// 赠送饭票数
			tradeLog.setRewardFanpiao(currentRecharge.getExtamout());
			// 支付金额
			tradeLog.setPayAmount(currentRecharge.getPrice());
			// 赠送饭票金额
			tradeLog.setRewardFanpiaoAmount(BigDecimalCalUtil.div(
					BigDecimalCalUtil.mul(new BigDecimal(currentRecharge.getExtamout()),
							new BigDecimal(fpExchangeRmb.getBeExchangeRatio())),
					new BigDecimal(fpExchangeRmb.getExchangeRatio())));
		} else {
			CurrencyRecharge currentRecharge = new CurrencyRecharge();
			currentRecharge.setId(0);
			currentRecharge.setAmount(tradeLog.getIncome());
			paymentExtendMap.put("currentRecharge", currentRecharge);
			// 根据充值饭票反算充值金额
			tradeLog.setPayAmount(BigDecimalCalUtil.div(
					BigDecimalCalUtil.mul(new BigDecimal(tradeLog.getIncome()),
							new BigDecimal(rmbExchangeFp.getExchangeRatio())),
					new BigDecimal(rmbExchangeFp.getBeExchangeRatio())));
			tradeLog.setRewardFanpiao(0);
			tradeLog.setRewardFanpiaoAmount(new BigDecimal(0));
		}
		// 计算总饭票数
		tradeLog.setIncomeAmount(tradeLog.getIncome() + tradeLog.getRewardFanpiao());
		if (paymentTypeEnum.getPaymentType() == PaymentTypeEnum.IOS_APPLE_PAY.getPaymentType()) { // 苹果内购充值计算
																									// 用户承担费用和实收金额
			// 实际收
			tradeLog.setExchangeAmount(BigDecimalCalUtil.div(
					BigDecimalCalUtil.mul(new BigDecimal(tradeLog.getIncome()),
							new BigDecimal(fpExchangeRmb.getBeExchangeRatio())),
					new BigDecimal(fpExchangeRmb.getExchangeRatio())));
			// 用户承担费用
			tradeLog.setChannelFee(BigDecimalCalUtil.sub(tradeLog.getPayAmount(), tradeLog.getExchangeAmount()));
		} else { // 非苹果内购充值 不计算用户承担费用 实收=支付金额
			tradeLog.setExchangeAmount(tradeLog.getPayAmount());
			tradeLog.setChannelFee(new BigDecimal(0));
		}
		// 验证支付额度是否正确
		if (BigDecimalCalUtil.compareTo(tradeLog.getPayAmount(), new BigDecimal(paymentTypeEnum.getPayMinVal())) < 0
				|| BigDecimalCalUtil.compareTo(tradeLog.getPayAmount(),
						new BigDecimal(paymentTypeEnum.getPayMaxVal())) > 0) {
			return new ResultBean(ResultCode.PayAcountIsError, null);
		}

		tradeLog.setNickName(user.getNickName());
		tradeLog.setUserType(user.getUserType());
		tradeLog.setPaySource(paymentTypeEnum.getPaySource());
		tradeLog.setAccountType(paymentTypeEnum.getAccountType());
		tradeLog.setPaymentType(paymentTypeEnum.getPaymentType());
		tradeLog.setPaymentExtend(JSON.toJSONString(paymentExtendMap));
		tradeLog.setIosProductCode(iosProductCode);
		vo.setClientIp(getIpAddr(request));
		vo.setPayAmount(String.valueOf(tradeLog.getPayAmount()));
		// 支付发起接口
		return payOpreateHandlerService.payOpreataHandler(paymentTypeEnum, tradeLog, vo);
	}

	/**
	 * 获取充值比例 和反计算比例
	 * 
	 * @param paymentTypeEnum
	 * @return
	 */
	private ResultBean<Map<String, CurrencyExchange>> findExchangeBeanInfo(PaymentTypeEnum paymentTypeEnum) {
		ResultBean<Map<String, CurrencyExchange>> resultBean = new ResultBean(ResultCode.SUCCESS, null);
		List<Integer> exchangeTypes = new ArrayList<Integer>();
		exchangeTypes.add(paymentTypeEnum.getCounterExchangeType());
		exchangeTypes.add(paymentTypeEnum.getExchangeRuleType());
		List<CurrencyExchange> exchangeList = currentRechargeService.queryCurrencyExchangeList(exchangeTypes);
		Map<String, CurrencyExchange> exchangeMap = new HashMap<String, CurrencyExchange>();
		if (exchangeList != null && !exchangeList.isEmpty()) {
			// 充值比例
			CurrencyExchange rmbExchangeFp = null;
			// 反计算比例
			CurrencyExchange fpExchangeRmb = null;
			for (CurrencyExchange exchangeTemp : exchangeList) {
				if (exchangeTemp.getExchangeRuleType() == paymentTypeEnum.getExchangeRuleType()) {
					rmbExchangeFp = exchangeTemp;
				} else if (exchangeTemp.getExchangeRuleType() == paymentTypeEnum.getCounterExchangeType()) {
					fpExchangeRmb = exchangeTemp;
				}
			}
			if (rmbExchangeFp == null || fpExchangeRmb == null) {
				// 兑换比例信息未配置
				resultBean = new ResultBean(ResultCode.PayExchangeRatioObjectIsEmpty, null);
			}
			if (rmbExchangeFp.getExchangeRatio() == 0 || rmbExchangeFp.getBeExchangeRatio() == 0
					|| fpExchangeRmb.getExchangeRatio() == 0 || fpExchangeRmb.getBeExchangeRatio() == 0) {
				// 兑换比系数为0
				resultBean = new ResultBean(ResultCode.PayExchangeRatioValIsZero, null);
			}

			exchangeMap.put("rmbExchangeFp", rmbExchangeFp);
			exchangeMap.put("fpExchangeRmb", fpExchangeRmb);
			resultBean.setData(exchangeMap);
		} else {
			// 兑换比例信息未配置
			resultBean = new ResultBean(ResultCode.PayExchangeRatioObjectIsEmpty, null);
		}
		return resultBean;
	}

	/**
	 * 获取赠送信息
	 * 
	 * @param status
	 * @param id
	 * @return
	 */
	private ResultBean<CurrencyRecharge> queryCurrencyRecharge(int status, int id) {
		CurrencyRecharge currencyRecharge = currentRechargeService.getCurrencyRechargeInfo(status, id);
		if (currencyRecharge == null) {
			return new ResultBean(ResultCode.PayCurrencyRechargeObjIsEmpty, null);
		}
		return new ResultBean<CurrencyRecharge>(ResultCode.SUCCESS, currencyRecharge);
	}

	/**
	 * 获取支付发起ip
	 * 
	 * @param request
	 * @return
	 */
	public String getIpAddr(HttpServletRequest request) {
		String ip = request.getRemoteAddr();
		if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
			ip = "127.0.0.1";
		}
		return ip;
	}

	/**
	 * 根据ID查询订单状态
	 * 
	 * @param orderId
	 * @return
	 */
	public TradeLog getTradeLogByOrderId(String orderId) {
		return tradeLogService.getTradeLogByOrderId(orderId);
	}

	/**
	 * 检查订单
	 * 
	 * @param orderId
	 * @return
	 */
	public boolean checkOrderId(String orderId) {
		if (tradeLogService.checkOrderId(orderId) > 0) {
			return true;
		} else {
			return false;
		}

	}

}
